feat: support multiple Slack/GitHub project integrations with TUI#38
Merged
markhallen merged 3 commits intomainfrom Mar 29, 2026
Merged
feat: support multiple Slack/GitHub project integrations with TUI#38markhallen merged 3 commits intomainfrom
markhallen merged 3 commits intomainfrom
Conversation
…figuration Add multi-project support allowing multiple Slack workspaces to be paired with different GitHub repositories. Projects are managed via an interactive TUI (tty-prompt) and stored in an AES-256-GCM encrypted config file. Incoming requests are routed by Slack team_id with env var fallback for full backward compatibility. Closes #34 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds support for configuring and routing multiple Slack workspace ↔ GitHub integrations, backed by an encrypted on-disk config and managed via an interactive terminal UI, while preserving env-var fallback for backward compatibility.
Changes:
- Introduces encrypted multi-project configuration storage and lookup by Slack
team_id. - Adds an interactive TUI + CLI entrypoint (and
rake config) to manage project integrations. - Updates Sinatra request handling to resolve tokens per-project with env-var fallback; adds tests covering multi-project routing and config/encryption.
Reviewed changes
Copilot reviewed 13 out of 15 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
app.rb |
Loads encrypted project config on startup; resolves credentials by team_id with fallback |
lib/config/encryption.rb |
AES-256-GCM + PBKDF2 encryption/decryption utilities |
lib/config/project_config.rb |
Multi-project model with CRUD, encrypted file I/O, team lookup |
lib/cli/tui.rb |
TUI for adding/editing/removing/listing projects |
bin/slack-gh-config |
CLI entry point for the TUI |
Rakefile |
Adds rake config task |
Gemfile / Gemfile.lock |
Adds TTY dependencies for TUI |
README.md |
Documents multi-project setup, config encryption, and usage |
CLAUDE.md |
Updates architecture/commands documentation |
test/test_app.rb |
Updates expectation for new missing-credentials error message |
test/test_multi_project.rb |
Adds integration tests for routing by team_id and fallback |
test/config/test_encryption.rb |
Adds encryption unit tests |
test/config/test_project_config.rb |
Adds project config unit tests |
test/cli/test_tui.rb |
Adds TUI flow tests with a mock prompt |
Comments suppressed due to low confidence (1)
lib/config/project_config.rb:62
update_projectapplies updates without re-validating invariants (non-emptyname/slack_team_id, uniqueness ofnameandslack_team_id). This allows edits that can break routing (e.g., blank/duplicate team IDs) or create duplicate names. Add the same validations used inadd_project(plus duplicate checks that exclude the current record) before persisting changes.
def update_project(name, attrs)
project = find_by_name(name)
raise ArgumentError, "Project '#{name}' not found" unless project
attrs.each do |key, value|
sym_key = key.to_sym
project[sym_key] = value if project.key?(sym_key)
end
project
- Log warning when config file exists but CONFIG_PASSPHRASE is unset - Rescue ArgumentError in decrypt for corrupted/non-Base64 data - Add blob length validation before attempting decryption - Enforce unique slack_team_id in add_project and validate on update - Require non-empty passphrases in TUI prompts - Replace send() with explicit lambda dispatch table in menu loop - Add required: true to team_id field in edit flow - Show restart reminder when exiting TUI with configured projects Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
bin/slack-gh-config/rake config) for adding, editing, removing, and listing project integrations.config/projects.enc— no database requiredteam_idwith automatic env var fallback for full backward compatibilityNew files
lib/config/encryption.rb— AES-256-GCM encryption with PBKDF2 key derivation (Ruby stdlib only)lib/config/project_config.rb— Multi-project config model with CRUD, encrypted file I/O, team_id lookuplib/cli/tui.rb— Interactive TUI using tty-prompt/tty-tablebin/slack-gh-config— CLI entry pointModified files
app.rb— Config loading on startup, team_id extraction, token resolution with fallbackGemfile— Added tty-prompt, tty-tableRakefile— Addedrake configtaskREADME.md— Multi-Project Setup section, updated features/env vars/structure/securityCLAUDE.md— Updated architecture and commandsCloses #34
Test plan
bundle exec rake cipasses (70 tests, 136 assertions, RuboCop clean)bundle exec rake configto verify TUI flow (add/list/edit/remove projects).config/projects.encand is not readable without passphraseCONFIG_PASSPHRASE, start server, send request with matching team_id🤖 Generated with Claude Code